package com.atguigu.tingshu.common.config.threadPool;

import com.atguigu.tingshu.common.properties.ThreadPoolProperties;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * <a href="https://www.shallowrecall.top/">Recall`Blog</a></br>
 * <a href="https://github.com/ShallowRecall">GitHub</a>
 *
 * @author Recall
 * @createTime 2025/03/20 20:08
 **/
@Configuration
@EnableConfigurationProperties(ThreadPoolProperties.class)
public class ThreadPoolAutoConfiguration {

    @Value("${spring.application.name}")
    public String appName;
    Logger logger = LoggerFactory.getLogger(this.getClass());


    /**
     * 自定义线程池对象
     */

    @Bean
    public ThreadPoolExecutor threadPoolExecutor(ThreadPoolProperties threadPoolProperties) {

        // 对于核心线程的设定
        // 任务类型
        // CPU密集型  N+1
        // IO密集型 2N
        // 实际核心线程数给多少通过压测来确定

        // int i = Runtime.getRuntime().availableProcessors();

        int corePoolSize = threadPoolProperties.getCorePoolSize();
        int maximumPoolSize = threadPoolProperties.getMaxPoolSize();
        long keepAliveTime = 30L;
        TimeUnit timeUnit = TimeUnit.SECONDS;
//        ArrayBlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(10);
        LinkedBlockingDeque<Runnable> blockingDeque = new LinkedBlockingDeque<>(threadPoolProperties.getQueueCapacity());
        AtomicInteger atomicInteger = new AtomicInteger(0);
        // 自定义线程工厂
        ThreadFactory threadFactory = new ThreadFactory() {
            @Override
            public Thread newThread(@NotNull Runnable r) {
                Thread thread = new Thread(r);
                thread.setName("my-customer-【" + appName + "】-" + atomicInteger.incrementAndGet());
                return thread;
            }
        };
        // 自定义拒绝策略
        RejectedExecutionHandler rejectedExecutionHandler = new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                logger.error("提交给线程池的任务：{}", r);
                throw new RejectedExecutionException("提交给线程池的任务被拒绝了");
            }
        };


        return new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                timeUnit,
                blockingDeque,
                threadFactory,
                rejectedExecutionHandler
        );
    }

}
